﻿using System;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace ProxyTool.Utils
{
    /// <summary>
    ///     文件操作类
    /// </summary>
    public class FileHelper : IDisposable
    {
        private bool _alreadyDispose;

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~FileHelper()
        {
            this.Dispose();
        }

        protected virtual void Dispose(bool isDisposing)
        {
            if (this._alreadyDispose)
            {
                return;
            }
            this._alreadyDispose = true;
        }

        /// <summary>
        ///     获取文件的扩展名
        /// </summary>
        /// <param name="filename">完整文件名</param>
        /// <returns>返回扩展名</returns>
        public static string GetPostfixStr(string filename)
        {
            var num = filename.LastIndexOf(".");
            var length = filename.Length;
            return filename.Substring(num, length - num);
        }

        /// <summary>
        ///     向指定文件写入内容
        /// </summary>
        /// <param name="path">要写入内容的文件完整路径</param>
        /// <param name="content">要写入的内容</param>
        public static void WriteFile(string path, string content)
        {
            try
            {
                var obj = new object();
                if (!File.Exists(path))
                {
                    var fileStream = File.Create(path);
                    fileStream.Close();
                }
                lock (obj)
                {
                    using (var streamWriter = new StreamWriter(path, false, Encoding.Default))
                    {
                        streamWriter.Write(content);
                        streamWriter.Close();
                        streamWriter.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ProxyToolException(string.Format("写入文件 {0} 异常:{1}", path, ex.Message));
            }
        }

        /// <summary>
        ///     向指定文件写入内容
        /// </summary>
        /// <param name="path">要写入内容的文件完整路径</param>
        /// <param name="content">要写入的内容</param>
        /// <param name="encoding">编码格式</param>
        public static void WriteFile(string path, string content, Encoding encoding)
        {
            try
            {
                var obj = new object();
                if (!File.Exists(path))
                {
                    var fileStream = File.Create(path);
                    fileStream.Close();
                }
                lock (obj)
                {
                    using (var streamWriter = new StreamWriter(path, false, encoding))
                    {
                        streamWriter.Write(content);
                        streamWriter.Close();
                        streamWriter.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ProxyToolException(string.Format("写入文件 {0} 异常:{1}", path, ex.Message));
            }
        }

        /// <summary>
        ///     读取文件内容
        /// </summary>
        /// <param name="path">要读取的文件路径</param>
        /// <returns>返回文件内容</returns>
        public static string ReadFile(string path)
        {
            string result;
            if (!File.Exists(path))
            {
                result = "不存在相应的目录";
            }
            else
            {
                var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                var streamReader = new StreamReader(stream, Encoding.Default);
                result = streamReader.ReadToEnd();
                streamReader.Close();
                streamReader.Dispose();
            }
            return result;
        }

        /// <summary>
        ///     读取文件内容
        /// </summary>
        /// <param name="path">要读取的文件路径</param>
        /// <param name="encoding">编码格式</param>
        /// <returns>返回文件内容</returns>
        public static string ReadFile(string path, Encoding encoding)
        {
            string result;
            if (!File.Exists(path))
            {
                result = "不存在相应的目录";
            }
            else
            {
                var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                var streamReader = new StreamReader(stream, encoding);
                result = streamReader.ReadToEnd();
                streamReader.Close();
                streamReader.Dispose();
            }
            return result;
        }

        /// <summary>
        ///     返回文件的完整路径
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <returns>返回文件的完整路径</returns>
        public static string GetAppFileFullName(string fileName)
        {
            return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
        }

        /// <summary>
        ///     从文件中读取第一行内容
        /// </summary>
        /// <param name="path">文件完整路径</param>
        /// <returns>返回文件第一行内容</returns>
        public static string GetFirstLine(string path)
        {
            string result;
            if (!File.Exists(path))
            {
                result = "不存在相应的目录";
            }
            else
            {
                var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                var streamReader = new StreamReader(stream, Encoding.Default);
                result = streamReader.ReadLine();
                streamReader.Close();
            }
            return result;
        }

        /// <summary>
        ///     读取文件第二行内容
        /// </summary>
        /// <param name="path">文件完整路径</param>
        /// <returns>返回读取的内容</returns>
        public static string GetSecondLine(string path)
        {
            string result;
            if (!File.Exists(path))
            {
                result = "不存在相应的目录";
            }
            else
            {
                var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                var streamReader = new StreamReader(stream, Encoding.Default);
                result = !string.IsNullOrEmpty(streamReader.ReadLine()) ? streamReader.ReadLine() : string.Empty;
                streamReader.Close();
            }
            return result;
        }

        /// <summary>
        ///     读取文件中指定位置的值
        /// </summary>
        /// <param name="path">文件完整路径</param>
        /// <param name="row">要读取的第几行</param>
        /// <param name="col">要读取的第几列</param>
        /// <returns>返回读取的内容</returns>
        public static string GetValue(string path, int row, int col)
        {
            string text;
            if (!File.Exists(path))
            {
                return "不存在相应的目录";
            }
            string[] array;
            if (row == 1)
            {
                text = GetFirstLine(path);
                array = text.Split(':');
            }
            else
            {
                text = GetSecondLine(path);
                array = text.Split(':');
            }
            return array[col];
        }

        /// <summary>
        ///     在文件末尾添加内容
        /// </summary>
        /// <param name="path">文件完整路径</param>
        /// <param name="content">要添加的内容</param>
        public static void FileAdd(string path, string content)
        {
            try
            {
                var obj = new object();
                lock (obj)
                {
                    var streamWriter = File.AppendText(path);
                    streamWriter.Write(content);
                    streamWriter.Flush();
                    streamWriter.Close();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("在文件{0}末尾添加内容异常:{1}", path, ex.Message), "异常提醒");
            }
        }

        /// <summary>
        ///     文件复制
        /// </summary>
        /// <param name="orignFile">源文件完整路径</param>
        /// <param name="newFile">目标文件完整路径</param>
        public static void FileCoppy(string orignFile, string newFile)
        {
            File.Copy(orignFile, newFile, true);
        }

        /// <summary>
        ///     删除文件
        /// </summary>
        /// <param name="path">要删除的文件的完整路径</param>
        public static void FileDel(string path)
        {
            File.Delete(path);
        }

        /// <summary>
        ///     文件移动（剪贴->粘贴）
        /// </summary>
        /// <param name="orignFile">源文件的完整路径</param>
        /// <param name="newFile">目标文件完整路径</param>
        public static void FileMove(string orignFile, string newFile)
        {
            File.Move(orignFile, newFile);
        }

        /// <summary>
        ///     创建目录
        /// </summary>
        /// <param name="orignFolder">当前目录</param>
        /// <param name="newFloder">要创建的目录名</param>
        public static void FolderCreate(string orignFolder, string newFloder)
        {
            Directory.SetCurrentDirectory(orignFolder);
            Directory.CreateDirectory(newFloder);
        }

        /// <summary>
        ///     删除目录
        /// </summary>
        /// <param name="dir">要删除的目录</param>
        public static void DeleteFolder(string dir)
        {
            if (!Directory.Exists(dir)) return;
            var fileSystemEntries = Directory.GetFileSystemEntries(dir);
            foreach (var text in fileSystemEntries)
            {
                if (File.Exists(text))
                {
                    File.Delete(text);
                }
                else
                {
                    DeleteFolder(text);
                }
            }
            Directory.Delete(dir);
        }

        /// <summary>
        ///     目录内容复制
        /// </summary>
        /// <param name="srcPath">源目录</param>
        /// <param name="aimPath">目标目录</param>
        public static void CopyDir(string srcPath, string aimPath)
        {
            try
            {
                if (aimPath[aimPath.Length - 1] != Path.DirectorySeparatorChar)
                {
                    aimPath += Path.DirectorySeparatorChar;
                }
                if (!Directory.Exists(aimPath))
                {
                    Directory.CreateDirectory(aimPath);
                }
                var fileSystemEntries = Directory.GetFileSystemEntries(srcPath);
                var array = fileSystemEntries;
                foreach (var text in array)
                {
                    if (Directory.Exists(text))
                    {
                        CopyDir(text, aimPath + Path.GetFileName(text));
                    }
                    else
                    {
                        File.Copy(text, aimPath + Path.GetFileName(text), true);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }
    }
}